Complex digital electronic components are designed using a Hardware Design Language (HDL), like VHDL, Verilog, SystemC, SystemVerilog and others. A design engineer types the description of a digital circuit in a textual format in a HDL. The HDL code can be simulated on a computer to validate the behaviour. After the behaviour of a digital design is validated, automated tools can translate the HDL design into a netlist, which lists the primitive components such as logical NAND ports or predefined memory blocks, interconnected by wires. Given this netlist as input and using many additional tools, a physical Application Specific Integrated Circuit (ASIC) can be made. Alternatively, the netlist can be programmed into a reconfigurable standard component, such as a Field Programmable Gate Array (FPGA). FIG. 1 provides as an example a portion of VHDL code (FIG. 1A) and a visual representation of its structure (FIG. 1B).
In the process of designing digital hardware, engineers often make modifications that require small changes to many files. Manually applying theses changes is time consuming and error prone.
Some HDLs are very verbose, i.e. they require a lot of text for expressing even simple concepts. Designs expressed in these languages contain a lot of redundant information, which needs to be kept consistent at all times. Again this is time consuming and error prone.
Once a design is near completion, it is very hard (and thus prohibitively expensive) to make drastic architectural changes. This difficulty is partly caused by the need to manually rewrite large portions of the design, which is time consuming and error prone.
For the same reasons, encapsulating and parameterizing legacy code is often prohibitively expensive. Because of this, opportunities for code reuse (and thus cost reduction) are lost.
Code refactoring, i.e. textual modification to program code, exists for software programming languages. The modification improves the internal structure of the code, while preserving the observable behaviour. Throughout the 1990s, most refactoring was done manually, but with the new millennium came robust automated refactoring tools for software languages. Most prominent examples are Eclipse (IBM) and JavaBeans (Sun) for Java and Refactor! (Microsoft) for the .NET languages. Refactoring differs from traditional code rewrite systems in that most of the program text is left unchanged. Traditional rewrite systems read a body of code, process it internally and produce an entire new body of code from the internal representation. Refactorings, on the other hand, produce localized, specific changes to the code. Since they leave the bulk of the code unchanged, a human design engineer can easily determine the scope and correctness of the proposed refactoring. Code refactoring works as a productivity tool in software engineering, as it significantly enhances operations like code review and bug fixing, code reuse and introducing enhancements and new features.
However, tools and methods for software refactoring cannot readily be applied to hardware refactoring, as software programming languages are fundamentally different from HDLs. Software code is translated into machine code, which is then sequentially executed by one or more instruction set processors. On the contrary, HDL code is translated to a netlist (i.e. a description of the connectivity of the electronic design), which is then placed and routed on a physical chip. This chip then contains a few thousand up to hundreds of millions transistors that are interconnected and all work in parallel. HDLs describe a spatial structure and contain an extremely accurate temporal description of the desired behaviour. Both these features are lacking in software languages.
Patents documents US2006/230366 and US2006/230367 relate to the reduction of XOR/NOR and AND/OR subexpressions in structural design representations, respectively. They are both concerned with the problem of verifying designs of digital circuits in order to make them error-free and flaw-free. The inventions disclose structural rewriting techniques that reform the logic of a netlist and eliminate redundancy. The disclosed systems read a body of code, process it internally and produce an entire new body of code from the internal representation.
Consequently, there is a need for a tool and method for the automated refactoring of hardware design language code.
Papers “Architecture Refinements by Code Refactoring of Behavioral VHDL-AMS Models” (Zeng et al., Proc. Int'l Symposium on Circuits and Systems ISCAS2006, May 2006, pp. 1475-1478) and “RAMS: A VHDL-AMS Code Refactoring Tool Supporting High Level Analog Synthesis” (Zeng et al., Proc. IEEE Computer Society Annual Symposium on VLSI, May 2005, pp. 266-257) refer to a tool for automatically rewriting description of analog hardware, e.g. analog integrators, multipliers and adders. This tool is not used for rewriting descriptions of digital hardware. The tool rewrites entire compilation units, rather than making local modifications to a body of text. This implies there is no textual similarity between the original text and the generated text.
The paper “A SystemVerilog Rewriting system for RTL Abstraction with Pentium Case Study” (Haynal et al., ACM/IEEE Intl Conference on Formal Methods and Models for Co-Design, Memocode 2008, pp. 79-88) describes a tool with capabilities for localized refactoring of hardware descriptions in the Verilog language. Since this tool operates on netlist representations, it is restricted to operations on the synthesizable subset of Verilog (see section 3.1 of the paper). This limitation means that automated code modifications are not possible for legal Verilog code that is meant only to be simulated. Important non-synthesizable code includes: test benches, behavioral models and assertions. Code containing syntax errors (such as missing colons at the end of a statement) or semantic errors (such as using a signal that was not previously declared) is certainly not synthesizable and cannot be processed by the described tools. The errors referred to in section 2 of the paper are merely behavioral errors: the code will correctly compile and synthesize to hardware, but the behavior of the hardware will be incorrect.
The solutions described by Zeng and Haynal operate on single compilation units (i.e. files). This means that each modification applies only to a single hardware component. Modifications of a global scope (across multiple files) are not covered. Useful global modifications include (a) adding new connections (wires) between hardware components or (b) modifications to constants or datatypes that are used in several components.